using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;

using Advent.aiDevices;

namespace Advent.Controls
{
    public partial class RingingCtrl : UserControl
    {

        private RingingGenerator Gen;

        #region Initialization etc

    

        public RingingCtrl()
        {
            InitializeComponent();

            /**************************************************************
             * Here we create some example ringing patterns and load them into 
             * combo boxes
             ************************************************************* */

            cbo_RingingPatterns.Items.Clear();
            cbo_RingingPatterns.Items.Add("None");

            // The Cadence class defines a single instance of an on/off pattern (not repeated)
            cbo_RingingPatterns.Items.Add(new Cadence("Single 1 second ring", TimeInterval.InSeconds(1)));


            // This creates the standard north american Ringing pattern
            cbo_RingingPatterns.Items.Add(new RepeatingCadence("Standard North American Ringing", TimeInterval.InSeconds(2), TimeInterval.InSeconds(4)));

            // This creates a double ring pattern with 2 500 millisecond burst starting every 4 seconds
            cbo_RingingPatterns.Items.Add(new RepeatingCadence("Double Ring", 
                                                                TimeInterval.InMilliseconds(500),       // on
                                                                TimeInterval.InMilliseconds(500),       // off
                                                                TimeInterval.InMilliseconds(500),       // on
                                                                TimeInterval.InSeconds(3.5)));          // off

            // This creates a ring pattern with 3 250 millisecond bursts starting every 4 seconds
            cbo_RingingPatterns.Items.Add(new RepeatingCadence( "Triple Ring", 
                                                                TimeInterval.InMilliseconds(250),       // on
                                                                TimeInterval.InMilliseconds(250),       // off
                                                                TimeInterval.InMilliseconds(250),       // on
                                                                TimeInterval.InMilliseconds(250),       // off
                                                                TimeInterval.InMilliseconds(250),       // on
                                                                TimeInterval.InSeconds(3)));            // off
            cbo_RingingPatterns.SelectedIndex = 0;

            /**************************************************************
             * Now we load the well defined waveshapes into the control
             ************************************************************* */

            cbo_Waveshape.Items.Clear();
            cbo_Waveshape.Items.Add(Waveshape.Sinusoiodal);
            cbo_Waveshape.Items.Add(Waveshape.Triangular);
            cbo_Waveshape.Items.Add(Waveshape.Square);


            this.EnabledChanged += new EventHandler(RingingCtrl_EnabledChanged);


        }

        void RingingCtrl_EnabledChanged(object sender, EventArgs e)
        {
            timer_Update.Enabled = Enabled;
        }
        
        /// <summary>
        /// Assigns a particular ringing generator for use with this control
        /// </summary>
        public void SetGenerator(RingingGenerator R)
        {
            Gen = R;
            RefreshControls();
            UpdateStatus();
            timer_Update.Interval = 1000;
            timer_Update.Enabled = true;
        }

        #endregion

        /// <summary>
        /// This returns a Ringing signal object defined by the user's settings
        /// </summary>
        Ringing GetUserRingingSettings()
        {
            double Level, Freq, DC;
            if (!double.TryParse(txt_Level.Text, out Level)) throw new Exception("Invalid ringing level");
            if (!double.TryParse(txt_Freq.Text, out Freq)) throw new Exception("Invalid ringing frequency");
            if (!double.TryParse(txt_DC.Text, out DC)) throw new Exception("Invalid dc level");
            return new Ringing(SignalLevel.InVrms(Level), Frequency.InHz(Freq), DCVoltage.InVolts(DC), (Waveshape)cbo_Waveshape.SelectedItem);
        }


        /// <summary>
        /// Refreshes the state of each control based on the tone generator
        /// </summary>
        private void RefreshControls()
        {
            try
            {
                if (Gen == null) return;
                txt_Freq.Text = Gen.Freq.Value.ToString();
                txt_Level.Text = Gen.Level.ToVrms().Value.ToString();
                txt_DC.Text = Gen.DC.Value.ToString();
                cbo_Waveshape.SelectedItem = Gen.Shape;
            }
            catch { }
        }

        private void UpdateStatus()
        {
            try
            {
                if (Gen == null) return;

                if (Gen.IsActive)
                {
                    gb_Ringing.Text = "Ringing Generator (Active)";
                }
                else
                {
                    gb_Ringing.Text = "Ringing Generator";
                }
            }
            catch { }
        }


        private void btn_StartRinging_Click(object sender, EventArgs e)
        {
            try
            {
                //Check if the item in the combobox is a signal pattern definition
                ISignalPattern P = cbo_RingingPatterns.SelectedItem as ISignalPattern;
                if (P != null)
                {
                    //if the user has selected a ringing pattern from the dropdown list then we set that value
                    Gen.Generate(GetUserRingingSettings(), P);
                }
                else
                {
                    // If the user hasn't specified a pattern then we enable ringing indefinitely
                    // Note: we could have passed null to the above definition too!
                    Gen.Generate(GetUserRingingSettings());
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btn_UpdateRinging_Click(object sender, EventArgs e)
        {
            try
            {
                Gen.Update(GetUserRingingSettings());
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }

        private void btn_StopRinging_Click(object sender, EventArgs e)
        {
            try
            {
                Gen.StopGenerator();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
            
        }

        private void timer_Update_Tick(object sender, EventArgs e)
        {
            try
            {

                UpdateStatus();
            }
            catch { }
        }

        private void btn_ResetToDefaults_Click(object sender, EventArgs e)
        {
            try
            {
                Gen.ResetToDefaults();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }
}
